﻿'// ========================================================================= '
'// ------------------------------------------------------------------------- '
'//!				\file		CM_ImageDb.vb
'			        \date		june 2010
'			        \author		TNick
'
'			        \brief		
'
'
'   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'   This file is considered universal knowledge. No restrictions
'   are imposed; use as you see fit.
'   Please read ReadMe.txt and Licence.txt in root folder
'   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'
'   The module expects (as default) a file named Images.xls in it's 
'   Misc folder
'
'// ------------------------------------------------------------------------- '
'// ========================================================================= '
'//
'//
'//
'//
'//  IMPORTS     ------------------------------------------------------------ '
#Region "Imports"

Imports System
Imports Microsoft.Win32
Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.Customization
Imports FSK_XL

'Imports Autodesk.AutoCAD.Colors
'Imports Autodesk.AutoCAD.GraphicsSystem

#End Region
'//  IMPORTS     ============================================================ '
'//
'//
'//
'//
'//  DEFINITIONS    --------------------------------------------------------- '
<Assembly: CommandClass(GetType(CM_ImageDb))> 


#Region "Public Structures"


'// --------------------------------------------------------------------- '
'// defines the settings for creating a grid
Public Structure IMGDBSTG
    Dim sDBPath As String ' location of database
    Dim sFavStr() As FAVIMG '// index of favorites images
    Dim bHasInit As Boolean
End Structure
'// ===================================================================== '

'// --------------------------------------------------------------------- '
'// runtime info about a working Excel sesion
Public Structure DBDATA
    Dim ExcelSheet As XLS
    Dim ExcelWorkbook As XLW

    Dim img_cnt As Integer
    Dim Rct As FSK_RECT
End Structure
'// ===================================================================== '

'// --------------------------------------------------------------------- '
'// runtime info about a image
Public Structure IMGDATA
    Dim sPath As String
    Dim sName As String
    Dim dNorth As Double
    Dim dEast As Double
    Dim dScale As Double
    Dim dRot As Double
End Structure
'// ===================================================================== '

'// --------------------------------------------------------------------- '
'// runtime info about a favorite image
Public Structure FAVIMG
    Dim id As IMGDATA
    Dim idx As Integer  '// 1 based index of row; 0 - bad input (ignore)
End Structure
'// ===================================================================== '

'// --------------------------------------------------------------------- '
'// full info about a image
Public Structure IMGFD
    Dim rtd As IMGDATA

    Dim dNorthMin As Double
    Dim dEastMin As Double
    Dim dNorthMax As Double
    Dim dEastMax As Double
End Structure
'// ===================================================================== '

'// --------------------------------------------------------------------- '
'// data stored about a file in georeference file
Public Structure IMGGEO
    Dim dXScale As Double
    Dim aAff_YsclX As Double
    Dim aAff_XsclY As Double
    Dim dYScale As Double
    Dim dX_UpprLft As Double
    Dim dY_UpprLft As Double
End Structure
'// ===================================================================== '


#End Region



'//  DEFINITIONS    ========================================================= '
'//
'//
'//
'//
'//  DATA    ---------------------------------------------------------------- '


'//  DATA    ================================================================ '
'//
'//
'//
'//
'//  CLASS    --------------------------------------------------------------- '
Public Class CM_ImageDb
    Inherits CModule


    '// --------------------------------------------------------------------- '
    '// DATA

#Region "Public Constants"
    '// name as displayed in various places
    Public Const sAPPNAME As String = "Image Database"
    '// version as displayed in various places
    Public Const sAPPVER As String = "1.0.0.0"
    '// short description
    Public sAPPTIP As String

    '// Command. Brings up the settings dialog
    Public Const sCMD_SETTINGS As String = "TNIK_IDB_STG"
    '// Command. Searches a line by a point
    Public Const sCMD_POINT As String = "TNIK_IDB_P"
    '// Command. Searches a line by a line
    Public Const sCMD_LINE As String = "TNIK_IDB_L"
    '// Command. Searches a line by a polyline
    Public Const sCMD_POLY As String = "TNIK_IDB_PL"
    '// Command. Searches a line by a countour
    Public Const sCMD_CONTOUR As String = "TNIK_IDB_C"
    '// Command. Redisplay last search
    Public Const sCMD_REDISPLAY As String = "TNIK_IDB_RD"
    '// Command. Add image
    Public Const sCMD_ADD As String = "TNIK_IDB_ADD"
    '// Command. Add folder
    Public Const sCMD_ADDF As String = "TNIK_IDB_AFLD"
    '// Command. Edit database
    Public Const sCMD_EDIT As String = "TNIK_IDB_EDIT"
    '// Command. Recreate database boundary
    Public Const sCMD_DBRECR As String = "TNIK_IDB_DBB"
    '// Command. Display the list of favorites images
    Public Const sCMD_FAV As String = "TNIK_IDB_FAV"




    ' first data row inside database
    Public Const DBF_Row_1 As Integer = 11
    ' first column of data in header
    Public Const DBF_HdrCol_1 As Integer = 2

    ' row for number of entries (in header)
    Public Const DBF_RowEntCnt As Integer = 2
    ' row for minimum north (in header)
    Public Const DBF_RowMinE As Integer = 3
    ' row for minimum Y (in header)
    Public Const DBF_RowMinN As Integer = 4
    ' row for maximum X (in header)
    Public Const DBF_RowMaxE As Integer = 5
    ' row for maximum Y (in header)
    Public Const DBF_RowMaxN As Integer = 6

    ' colmn that has path information
    Public Const DBF_ColPath As Integer = 1
    ' colmn that has name of file
    Public Const DBF_ColName As Integer = 2
    ' colmn that has E1
    Public Const DBF_ColEmin As Integer = 3
    ' colmn that has N1
    Public Const DBF_ColNmin As Integer = 4
    ' colmn that has E2
    Public Const DBF_ColEmax As Integer = 5
    ' colmn that has N2
    Public Const DBF_ColNmax As Integer = 6
    ' colmn that has X of insertion point
    Public Const DBF_ColEins As Integer = 7
    ' colmn that has Y of insertion point
    Public Const DBF_ColNins As Integer = 8
    ' colmn that has the scale to be applied
    Public Const DBF_ColScl As Integer = 9
    ' colmn that has the rotation to be applied
    Public Const DBF_ColRot As Integer = 10




#End Region



    '// this is where the settings are stored durring run-time
    Public Shared Stgs As IMGDBSTG

    '// array of cached images from last search
    Public iAry() As IMGDATA

    '// ===================================================================== '


#Region "Public Shared Functions"


    '// --------------------------------------------------------------------- '
    '// gets the collection of images references that have same definition
    Public Shared Function GetRefsImg( _
        ByRef acDoc As Document, _
        ByRef acRsImg As RasterImageDef) _
        As ObjectIdCollection
        '// document is assumed to be locked

        Dim acOidC As New ObjectIdCollection

        Using acTrans As Transaction = acDoc.Database. _
            TransactionManager.StartTransaction()
            Try
                '// get a reference to table of blocks
                Dim acBlkTbl As BlockTable = DirectCast( _
                        acTrans.GetObject(acDoc.Database.BlockTableId, _
                                          OpenMode.ForRead),  _
                    BlockTable)
                ' Get Model space (is just a block)
                Dim acBlkModel As BlockTableRecord = DirectCast( _
                        acTrans.GetObject( _
                        acBlkTbl(BlockTableRecord.ModelSpace), _
                        OpenMode.ForRead),  _
                    BlockTableRecord)
                '// iterate in all objects
                For Each acOid As ObjectId In acBlkModel
                    Dim acDbE As DBObject = DirectCast( _
                        acTrans.GetObject( _
                            acOid, _
                            OpenMode.ForRead),  _
                        DBObject)

                    If TypeOf acDbE Is RasterImage Then
                        Dim acRI As RasterImage = _
                            DirectCast(acDbE, RasterImage)
                        If (acRI.ImageDefId = acRsImg.Id) Then
                            acOidC.Add(acOid)
                        End If
                    End If
                Next

                acTrans.Abort()
            Catch ex As System.Exception
                acTrans.Abort()
                CMain.DebugException(ex)
            End Try
        End Using

        Return acOidC

    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// Tell if an image is xref'ed in a drawing;
    '// returns the entry for the image
    Public Shared Function IsImgInDoc( _
        ByRef acDoc As Document, _
        ByRef Pth As String, _
        ByRef Name As String) As RasterImageDef
        '// document is assumed to be locked

        If (acDoc Is Nothing) Then Return Nothing
        Dim ImageDicID As ObjectId
        Dim ImageDic As DBDictionary
        Dim RasterDef As RasterImageDef = Nothing
        Dim sSrcPth As String = (Pth & Name).ToUpper()

        Using acTrans As Transaction = acDoc.Database. _
            TransactionManager.StartTransaction()
            Try
                '// if there is no dictionary, there can't be any image
                ImageDicID = RasterImageDef. _
                    GetImageDictionary(acDoc.Database)
                If ImageDicID.IsNull Then
                    Exit Try
                End If
                ImageDic = DirectCast(acTrans.GetObject(ImageDicID, _
                           DatabaseServices.OpenMode.ForRead),  _
                        DBDictionary)
                If ImageDic Is Nothing Then
                    Exit Try
                End If
                '// iterate in all entries
                For Each acDicE As DBDictionaryEntry In ImageDic
                    '// get image definition for this entry
                    RasterDef = DirectCast(acTrans.GetObject(acDicE.Value, _
                       DatabaseServices.OpenMode.ForRead),  _
                       RasterImageDef)
                    If (RasterDef.ActiveFileName.ToUpper() = sSrcPth) Or _
                       (RasterDef.SourceFileName.ToUpper() = sSrcPth) Then
                        Exit Try
                    End If
                Next
                RasterDef = Nothing
                acTrans.Abort()
            Catch ex As System.Exception
                acTrans.Abort()
                CMain.DebugException(ex)
            End Try
        End Using
        Return RasterDef
    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// get informations about an image
    Public Shared Sub GetRstInfo( _
        ByRef acDoc As Document, _
        ByRef acRID As RasterImageDef, _
        ByRef acRI As RasterImage, _
        ByRef OutPt As IMGFD)

        Dim sPth As String
        Dim prvu As Autodesk.AutoCAD.DatabaseServices.UnitsValue
        prvu = acDoc.Database.Insunits

        acDoc.Database.Insunits = UnitsValue.Undefined
        'Autodesk.AutoCAD.DatabaseServices.Unit
        If System.IO.File.Exists(acRID.ActiveFileName) Then
            sPth = acRID.ActiveFileName
        Else
            sPth = acRID.SourceFileName
        End If
        Dim i As Integer
        i = sPth.LastIndexOf("\")
        If (i > 0) Then
            OutPt.rtd.sPath = Nothing
            OutPt.rtd.sName = sPth
        Else
            OutPt.rtd.sPath = sPth.Substring(0, i)
            OutPt.rtd.sName = sPth.Substring(i + 1)
        End If

        OutPt.dEastMin = _
            acRI.GeometricExtents.MaxPoint.X - _
            Math.Abs(acRI.Orientation.Yaxis.X) - _
            Math.Abs(acRI.Orientation.Xaxis.X)

        OutPt.dNorthMin = _
            acRI.GeometricExtents.MaxPoint.Y - _
            Math.Abs(acRI.Orientation.Yaxis.Y) - _
            Math.Abs(acRI.Orientation.Xaxis.Y)

        OutPt.dEastMax = _
            acRI.GeometricExtents.MaxPoint.X

        OutPt.dNorthMax = _
            acRI.GeometricExtents.MaxPoint.Y

        OutPt.rtd.dNorth = _
            acRI.Orientation.Origin.Y

        OutPt.rtd.dEast = _
            acRI.Orientation.Origin.X

        OutPt.rtd.dScale = _
            acRI.Scale.X / 2500

        Dim dTmpDbl = Math.Atan2( _
            acRI.Orientation.Xaxis.Y, _
            acRI.Orientation.Xaxis.X)
        'If (dTmpDbl < 0) Then
        '    dTmpDbl = Math.PI * 2 - dTmpDbl
        'End If
        If (Math.Abs(dTmpDbl) < CMain.MARGIN) Then
            dTmpDbl = 0
        End If
        OutPt.rtd.dRot = dTmpDbl
        acDoc.Database.Insunits = prvu

    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// compare two images and tell if they are the same
    Public Shared Function IsSameLoc( _
        ByRef i1 As IMGDATA, _
        ByRef i2 As IMGDATA) _
        As Boolean

        If Math.Abs(i1.dEast - i2.dEast) < CMain.MARGIN Then
            If Math.Abs(i1.dNorth - i2.dNorth) < CMain.MARGIN Then
                If Math.Abs(i1.dRot - i2.dRot) < CMain.MARGIN Then
                    If Math.Abs(i1.dScale - i2.dScale) < CMain.MARGIN Then
                        Return True
                    End If
                End If
            End If
        End If
        Return False
    End Function
    '// ===================================================================== '

#End Region



#Region "Private general purpose Functions"


    '// --------------------------------------------------------------------- '
    '// This function saves current settings
    Private Shared Sub SaveSett()

        CSett.SaveStg(sAPPNAME, "Stgs.sDBPath", Stgs.sDBPath)
        If (Stgs.sFavStr IsNot Nothing) Then
            Dim sOuyt As String = ""
            For Each sE As FAVIMG In Stgs.sFavStr
                If (sE.idx > 0) Then
                    sOuyt = sOuyt & CStr(sE.idx) & ","
                End If
            Next
            CSett.SaveStg(sAPPNAME, "Stgs.sFavStr", sOuyt)
        End If
    End Sub
    '// ===================================================================== '


    '// --------------------------------------------------------------------- '
    '// This function loads current settings
    Private Shared Sub GetSett()
        Try

            Stgs.sFavStr = Nothing
            Stgs.bHasInit = False
            Stgs.sDBPath = CSett.GetStrStg(sAPPNAME, "Stgs.sDBPath", _
                CApp.sAppPath & "Misc\Images.xls")
            If (Stgs.sDBPath = "") Then
                Stgs.sDBPath = CApp.sAppPath & "Misc\Images.xls"
            End If
            Dim sStrFav As String = CSett.GetStrStg(sAPPNAME, "Stgs.sFavStr", "")
            If (Not String.IsNullOrEmpty(sStrFav)) Then
                Dim cSep(0) As Char
                Dim iVal As Integer
                cSep(0) = ","c
                Dim sAryS() As String = sStrFav.Split(cSep, _
                    System.StringSplitOptions.RemoveEmptyEntries)
                For Each sVal As String In sAryS
                    Try
                        iVal = CInt(sVal)
                        If (Stgs.sFavStr Is Nothing) Then
                            ReDim Stgs.sFavStr(0 To 0)
                        Else
                            ReDim Preserve Stgs.sFavStr(0 To Stgs.sFavStr.Length)
                        End If
                        With Stgs.sFavStr(Stgs.sFavStr.Length - 1)
                            .idx = iVal
                        End With
                    Catch ex As System.Exception
                        Debug.Print("Invalid entry spotted in " & _
                                "ImageDb settings for favorites: " & sVal)
                    End Try
                Next
            End If
        Catch ex As System.Exception
            CMain.DebugException(ex)
        End Try
    End Sub
    '// ===================================================================== '


    '// --------------------------------------------------------------------- '
    '// This function shows current settings
    Private Shared Function PrintStg(ByRef lcStg As IMGDBSTG) As String

        Return ( _
         vbCrLf & CMain._T(TX.CSTG) & sAPPNAME & ": " & vbCrLf & _
          CMain._T(TX.DBFPATH) & " = " & lcStg.sDBPath & vbCrLf)

    End Function
    '// ===================================================================== '

#End Region


#Region "Common interface" ' -----------------------

    '// --------------------------------------------------------------------- '
    '// a new instance is created
    Public Sub New()
        Try
            sAPPTIP = CMain._T(TX.IDB_INFO)
            Return
        Catch ex As System.Exception
            CMain.DebugException(ex)
            Return
        End Try
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// the module is asked to terminate
    Public Overrides Function Terminate() As Boolean
        Try
            SaveSett()
            Return True
        Catch ex As System.Exception
            CMain.DebugException(ex)
            Return False
        End Try
    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// the module is asked to tell it's name
    Public Shared Function GetName() As String
        Return sAPPNAME
    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// the module is asked to tell about itself
    Public Shared Sub GetInfos(ByRef sName As String, ByRef sVer As String, ByRef sTip As String)
        sName = sAPPNAME
        sVer = sAPPVER
        sTip = CMain._T(TX.IDB_INFO)
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// the module is asked to tell about itself
    Public Shared Function GetDescription() As String
        Dim sOut As String = sAPPNAME
        Try
            Dim cIni As New IniWork(CApp.sAppPath & CMain.APPSTG)
            If cIni.HasErrors = True Then Exit Try
            sOut = cIni.Read(sAPPNAME, CMain.DESCRKEY & _
                             CMain.eAppLang.ToString, sAPPNAME)
        Catch ex As System.Exception
            CMain.DebugException(ex)
        End Try
        Return sOut
    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// the module is informed about application start-up
    Public Shared Sub DoPrereq()
        Try
            ' this function is called at application start-up in order to 
            ' allow applications to do any prerequisites
            ' there is no instance of this class at this time
            GetSett()
        Catch ex As System.Exception
            CMain.DebugException(ex)
        End Try
        Return
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// create the user interface for this module
    Public Shared Sub DoCUI( _
     ByRef pcs As CustomizationSection, _
     ByRef mg As MacroGroup)
        ' this function is called when a CUI is builded in order to
        ' allow any application specifics
        Try
#If HARDCORE_CUI Then
            If CApp.cuiCl Is Nothing Then Exit Try
            CApp.cuiCl.AddMacro(sCMD_POINT, "IMG_Point")
            CApp.cuiCl.AddMacro(sCMD_LINE, "IMG_Line")
            CApp.cuiCl.AddMacro(sCMD_POLY, "IMG_Poly")
            CApp.cuiCl.AddMacro(sCMD_CONTOUR, "IMG_Contour")
            CApp.cuiCl.AddMacro(sCMD_REDISPLAY, "IMG_List")
            CApp.cuiCl.AddMacro(sCMD_ADD, "IMG_AddFile")
            CApp.cuiCl.AddMacro(sCMD_ADDF, "IMG_AddFolder")
            CApp.cuiCl.AddMacro(sCMD_EDIT, "IMG_Edit")
            CApp.cuiCl.AddMacro(sCMD_SETTINGS, "IMG_Settings")
            CApp.cuiCl.AddMacro(sCMD_FAV, "IMG_Fav")

            CApp.cuiCl.AddToolbar( _
                sAPPNAME, _
                Application.MainWindow.Location.X, _
                100 + MIDS.IMGDB * 30)
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.FAV), sCMD_FAV)
            CApp.cuiCl.AddToolbarSep()
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.POINT), sCMD_POINT)
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.LINE), sCMD_LINE)
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.POLY), sCMD_POLY)
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.CONTOUR), sCMD_CONTOUR)
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.REDISP), sCMD_REDISPLAY)
            CApp.cuiCl.AddToolbarSep()
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.ADDIMG), sCMD_ADD)
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.ADDFOLD), sCMD_ADDF)
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.SHOWDBF), sCMD_EDIT)
            CApp.cuiCl.AddToolbarSep()
            CApp.cuiCl.AddToolbarBtn(CMain._T(TX.SETTINGS), sCMD_SETTINGS)

#Else
			Dim mm1 As MenuMacro = Nothing
			mm1 = New MenuMacro(mg, sCMD_POINT, "^C^C" & sCMD_POINT, _
                "ID_" & sCMD_POINT)
			mm1 = New MenuMacro(mg, sCMD_LINE, "^C^C" & sCMD_LINE, _
                "ID_" & sCMD_LINE)
			mm1 = New MenuMacro(mg, sCMD_POLY, "^C^C" & sCMD_POLY, _
                "ID_" & sCMD_POLY)
			mm1 = New MenuMacro(mg, sCMD_CONTOUR, "^C^C" & sCMD_CONTOUR, _
                "ID_" & sCMD_CONTOUR)
            mm1 = New MenuMacro(mg, sCMD_REDISPLAY, "^C^C" & sCMD_REDISPLAY, _
                "ID_" & sCMD_REDISPLAY)
            mm1 = New MenuMacro(mg, sCMD_ADD, "^C^C" & sCMD_ADD, _
                "ID_" & sCMD_ADD)
            mm1 = New MenuMacro(mg, sCMD_ADDF, "^C^C" & sCMD_ADDF, _
                "ID_" & sCMD_ADDF)
            mm1 = New MenuMacro(mg, sCMD_EDIT, "^C^C" & sCMD_EDIT, _
                "ID_" & sCMD_EDIT)
			mm1 = New MenuMacro(mg, sCMD_SETTINGS, "^C^C" & sCMD_SETTINGS, _
                "ID_" & sCMD_SETTINGS)
			mm1 = New MenuMacro(mg, sCMD_FAV, "^C^C" & sCMD_FAV, _
                "ID_" & sCMD_FAV)


			Dim tbBtn As ToolbarButton = Nothing
			Dim newTb As Toolbar = New Toolbar(sAPPNAME, pcs.MenuGroup)
			newTb.ElementID = "EID_TNIK_IMDB"
			newTb.ToolbarOrient = ToolbarOrient.floating
			newTb.ToolbarVisible = ToolbarVisible.show
            newTb.XCoordinate = Application.MainWindow.Location.X
            newTb.YCoordinate = 100 + MIDS.IMGDB * 30


			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.FAV)
			tbBtn.MacroID = "ID_" & sCMD_FAV
			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.POINT)
			tbBtn.MacroID = "ID_" & sCMD_POINT
			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.LINE)
			tbBtn.MacroID = "ID_" & sCMD_LINE
			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.POLY)
			tbBtn.MacroID = "ID_" & sCMD_POLY
			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.CONTOUR)
			tbBtn.MacroID = "ID_" & sCMD_CONTOUR
			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.REDISP)
			tbBtn.MacroID = "ID_" & sCMD_REDISPLAY

			tbBtn = New ToolbarButton(newTb, -1) ' separator

			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.ADDIMG)
			tbBtn.MacroID = "ID_" & sCMD_ADD
			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.ADDFOLD)
			tbBtn.MacroID = "ID_" & sCMD_ADDF
			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.SHOWDBF)
			tbBtn.MacroID = "ID_" & sCMD_EDIT

			tbBtn = New ToolbarButton(newTb, -1) ' separator

			tbBtn = New ToolbarButton(newTb, -1)
			tbBtn.Name = CMain._T(tx.SETTINGS)
			tbBtn.MacroID = "ID_" & sCMD_SETTINGS

#End If
        Catch ex As System.Exception
            CMain.DebugException(ex)
        End Try
    End Sub
    '// ===================================================================== '

#End Region


#Region "Internal base work"

    '// --------------------------------------------------------------------- '
    '// Before any querries are made to DB, it has to be started
    Public Shared Function Start_DB(ByRef sData As DBDATA) As Boolean
        Dim bRet As Boolean = False
        Try
            sData.ExcelWorkbook = Nothing
            sData.ExcelSheet = Nothing
            Debug.Print("STARTING EXCEL ..." & Stgs.sDBPath)
            sData.ExcelWorkbook = New XLW(Stgs.sDBPath)
            Debug.Print("Checking...")
            If (sData.ExcelWorkbook.ErrSts <> FSK_XL.XLW.ERR.OK) Then
                Debug.Print("error " & sData.ExcelWorkbook.ErrSts)
                Select Case sData.ExcelWorkbook.ErrSts
                    Case FSK_XL.XLW.ERR.NOTAFILE
                        CMain.AlertUser(CMain._T(TX.IMGE_DB) & vbNewLine & _
                            Stgs.sDBPath & vbNewLine & _
                            CMain._T(TX.ERR_FILE))
                    Case Else
                        CMain.AlertUser(TX.IMGE_DB & vbNewLine & _
                                        sData.ExcelWorkbook.ErrSts.ToString)
                End Select
                Stop_DB(sData)
                Exit Try
            Else
                Debug.Print("no error ")
            End If
            sData.ExcelSheet = sData.ExcelWorkbook.GetActiveSheet()
            If (sData.ExcelWorkbook.ErrSts <> FSK_XL.XLW.ERR.OK) Then
                sData.ExcelWorkbook.Close()
                sData.ExcelWorkbook = Nothing
                sData.ExcelSheet = Nothing
                Exit Try
            End If
            '// these functions only modify bRet (to False) in case
            '// of failure (can't convert, no value, ...
            bRet = True
            sData.img_cnt = sData.ExcelSheet.GetCVInt( _
                DBF_RowEntCnt, DBF_HdrCol_1, bRet)
            sData.Rct.E_1 = sData.ExcelSheet.GetCVDbl( _
                DBF_RowMinE, DBF_HdrCol_1, bRet)
            sData.Rct.N_1 = sData.ExcelSheet.GetCVDbl( _
                DBF_RowMinN, DBF_HdrCol_1, bRet)
            sData.Rct.E_2 = sData.ExcelSheet.GetCVDbl( _
                DBF_RowMaxE, DBF_HdrCol_1, bRet)
            sData.Rct.N_2 = sData.ExcelSheet.GetCVDbl( _
                DBF_RowMaxN, DBF_HdrCol_1, bRet)
            '//bRet = True
        Catch ex As System.Exception
            Debug.Print("Start_DB exception:")
            CMain.DebugException(ex)
            If TypeOf ex Is TypeInitializationException Then
                Debug.Print("TypeInitializationException...")
                Dim tie As TypeInitializationException
                tie = DirectCast(ex, TypeInitializationException)
                CMain.DebugException(tie.InnerException)
            End If

            Stop_DB(sData)
            CMain.AlertUser(TX.IMGE_DB)
        End Try
        Return bRet
    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// after querries are made to DB, it has to be closed
    Public Shared Sub Stop_DB(ByRef sData As DBDATA)
        If Not (sData.ExcelWorkbook Is Nothing) Then
            sData.ExcelSheet = Nothing
            Call sData.ExcelWorkbook.Close()
            sData.ExcelWorkbook = Nothing
        End If
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// add an image to internal cache
    '// enshure uniqueness
    Private Sub AppendImgToCh( _
        ByRef sData As DBDATA, _
        ByRef iMax As Integer, _
        ByRef ICrt As Integer, _
        ByVal i As Integer)

        If (iMax = -1) Then
            ReDim iAry(0 To 10)
            iMax = 10
            ICrt = 0
        Else
            Dim inf As IMGDATA
            Dim bOk As Boolean = True
            '// bOk is only modified (to False) in case of failure
            inf.sName = _
                sData.ExcelSheet.GetCVStr( _
                i, DBF_ColName)
            inf.sPath = _
                sData.ExcelSheet.GetCVStr( _
                i, DBF_ColPath)
            inf.dNorth = _
                sData.ExcelSheet.GetCVDbl( _
                i, DBF_ColNins, bOk)
            inf.dEast = _
                sData.ExcelSheet.GetCVDbl( _
                i, DBF_ColEins, bOk)
            inf.dScale = _
                sData.ExcelSheet.GetCVDbl( _
                i, DBF_ColScl, bOk)
            inf.dRot = _
                sData.ExcelSheet.GetCVDbl( _
                i, DBF_ColRot, bOk)
            If (bOk = False) Then
                CMain.InformUser(String.Format(CMain._T(TX.ERR_GETIMGXL), i))
            End If

            For j As Integer = 0 To ICrt - 1
                If (inf.sName.ToUpper() = iAry(j).sName.ToUpper()) Then
                    If Math.Abs(inf.dNorth - iAry(j).dNorth) < CMain.MARGIN Then
                        If Math.Abs(inf.dEast - iAry(j).dEast) < CMain.MARGIN Then
                            If Math.Abs(inf.dScale - iAry(j).dScale) < CMain.MARGIN Then
                                If Math.Abs(inf.dRot - iAry(j).dRot) < CMain.MARGIN Then
                                    Return
                                End If
                            End If
                        End If
                    End If
                End If
            Next

            If (ICrt > iMax) Then
                iMax = iMax + 10
                ReDim Preserve iAry(0 To iMax)
            End If
            '// this image holds requested point
            iAry(ICrt) = inf
            ICrt = ICrt + 1
        End If
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// runtime info about a image
    Private Structure RECURENTFS
        Dim db As DBDATA
        Dim acDoc As Document
        Dim acTrans As Transaction
        Dim lTot As Integer
        Dim dlgPB As PROGRESS
        Dim bCancel As Boolean
        Dim iAdded As Integer
    End Structure
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// Tells if a string is an image file extension
    Private Function IsImageFile(ByVal strPath As String) As Boolean

        Select Case strPath.ToUpper()
            Case ".JPG", ".JPEG", ".BMP", ".TIF", ".TIFF", ".ECW", ".PNG"
                Return True
            Case Else
                Return False
        End Select

    End Function
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    Private Sub AppendRcToDb( _
        ByRef RcData As RECURENTFS, _
        ByRef fi As System.IO.FileInfo)

        '// determine if it has parameters
        '// if so, add to db
        Dim objReader As System.IO.StreamReader = Nothing
        Dim objImage As System.Drawing.Image = Nothing
        Dim sExt As String
        Dim sFGeo As String
        Dim i As Integer = fi.FullName.LastIndexOf(".")

        Try
            If i < 0 Then Return
            sExt = fi.FullName.Substring(i + 1)
            Select Case sExt.ToUpper()
                Case "TIF", "TIFF"
                    sExt = "TFW"
                Case "JPEG", "JPG"
                    sExt = "JGW"
                Case "TIF", "TIFF"
                    sExt = "TFW"
                Case "PNG"
                    sExt = "PGW"
                Case "BMP"
                    sExt = "BPW"
                Case "ECW"
                    sExt = "EWW"
                Case Else
                    Exit Try
            End Select
            '// get the name of georeference file
            sFGeo = fi.FullName.Substring(0, i + 1) & sExt
            '// and see if there is such thing
            i = 0
            Dim geo As IMGGEO
            If (System.IO.File.Exists(sFGeo)) Then
                objReader = New System.IO.StreamReader(sFGeo)
                Dim TextLine As String
                Do While objReader.Peek() <> -1
                    TextLine = objReader.ReadLine().Trim
                    If TextLine.Length > 0 Then
                        Select Case i
                            Case 0
                                geo.dXScale = CDbl(TextLine)
                            Case 1
                                geo.aAff_YsclX = CDbl(TextLine)

                            Case 2
                                geo.aAff_XsclY = CDbl(TextLine)

                            Case 3
                                geo.dYScale = CDbl(TextLine)

                            Case 4
                                geo.dX_UpprLft = CDbl(TextLine)

                            Case 5
                                geo.dY_UpprLft = CDbl(TextLine)

                            Case Else
                                Debug.Print("Geo file corrupt: too manny lines")
                                objReader.Close()
                                objReader = Nothing
                                Exit Try

                        End Select
                        i = i + 1
                    End If
                Loop
                If i <> 6 Then
                    Debug.Print("Geo file corrupt: too few lines")
                    Exit Try
                End If

                ' Load the Image
                objImage = _
                    System.Drawing.Image.FromFile(fi.FullName)
                '// get other 3 corners
                Dim BL_x As Double, BL_y As Double
                Dim UR_x As Double, UR_y As Double
                Dim BR_x As Double, BR_y As Double

                'x = geo.dXScale * column + geo.aAff_XsclY * row + geo.dX_UpprLft
                'y = geo.aAff_YsclX * row + geo.dYScale * column + geo.dY_UpprLft
                BL_x = geo.dXScale * 0 + geo.aAff_XsclY * objImage.Height + geo.dX_UpprLft
                BL_y = geo.aAff_YsclX * objImage.Height + geo.dYScale * 0 + geo.dY_UpprLft

                UR_x = geo.dXScale * objImage.Width + geo.aAff_XsclY * 0 + geo.dX_UpprLft
                UR_y = geo.aAff_YsclX * 0 + geo.dYScale * objImage.Width + geo.dY_UpprLft

                BR_x = geo.dXScale * objImage.Width + geo.aAff_XsclY * objImage.Height + geo.dX_UpprLft
                BR_y = geo.aAff_YsclX * objImage.Height + geo.dYScale * objImage.Width + geo.dY_UpprLft

                Dim idata As IMGFD
                i = fi.FullName.LastIndexOf("\")
                If i < 0 Then
                    idata.rtd.sName = fi.FullName
                    idata.rtd.sPath = ""
                Else
                    idata.rtd.sName = fi.FullName.Substring(i + 1)
                    idata.rtd.sPath = fi.FullName.Substring(0, i + 1)
                End If

                idata.dEastMin = Math.Min(Math.Min(BL_x, UR_x), Math.Min(BR_x, geo.dX_UpprLft))
                idata.dEastMax = Math.Max(Math.Max(BL_x, UR_x), Math.Max(BR_x, geo.dX_UpprLft))
                idata.dNorthMin = Math.Min(Math.Min(BL_y, UR_y), Math.Min(BR_y, geo.dX_UpprLft))
                idata.dNorthMax = Math.Max(Math.Max(BL_y, UR_y), Math.Max(BR_y, geo.dY_UpprLft))
                idata.rtd.dEast = BL_x
                idata.rtd.dNorth = BL_y
                Dim dDX As Double = BR_x - BL_x, dDY As Double = BR_y - BL_y
                idata.rtd.dScale = Math.Sqrt(Math.Pow(dDX, 2) + _
                                             Math.Pow(dDY, 2)) / _
                                   objImage.Width
                idata.rtd.dRot = Math.Atan2(BL_y, BL_x)

                i = RcData.db.img_cnt + DBF_Row_1
                RcData.db.ExcelSheet.SetCV _
                    (i, DBF_ColPath, idata.rtd.sPath)
                RcData.db.ExcelSheet.SetCV _
                    (i, DBF_ColName, idata.rtd.sName)
                RcData.db.ExcelSheet.SetCV _
                    (i, DBF_ColEmin, idata.dEastMin)
                RcData.db.ExcelSheet.SetCV _
                    (i, DBF_ColNmin, idata.dNorthMin)
                RcData.db.ExcelSheet.SetCV _
                    (i, DBF_ColNmax, idata.dNorthMax)
                RcData.db.ExcelSheet.SetCV _
                    (i, DBF_ColEmax, idata.dEastMax)
                RcData.db.ExcelSheet.SetCV _
                    (i, DBF_ColEins, idata.rtd.dEast)
                RcData.db.ExcelSheet.SetCV _
                    (i, DBF_ColNins, idata.rtd.dNorth)
                RcData.db.ExcelSheet.SetCV _
                    (i, DBF_ColScl, idata.rtd.dScale)
                RcData.db.ExcelSheet.SetCV _
                    (i, DBF_ColRot, idata.rtd.dRot)

                '// update the header
                RcData.db.img_cnt = RcData.db.img_cnt + 1
                RcData.db.ExcelSheet.SetCV _
                    (DBF_RowEntCnt, DBF_HdrCol_1, RcData.db.img_cnt)
                RcData.iAdded = RcData.iAdded + 1
            End If

        Catch ex As System.Exception
            CMain.DebugException(ex)
        Finally
            If Not objImage Is Nothing Then
                objImage.Dispose()
                objImage = Nothing
            End If
            If Not objReader Is Nothing Then
                objReader.Close()
                objReader = Nothing
            End If
        End Try

    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    Private Sub RecFindImg(ByRef RcData As RECURENTFS, ByVal strPath As String)
        Dim oDir As New System.IO.DirectoryInfo(strPath)
        Dim oSubDir() As System.IO.DirectoryInfo
        Dim oFiles() As System.IO.FileInfo
        Dim i As Int32

        If (RcData.bCancel = True) Then Return
        oFiles = oDir.GetFiles
        oSubDir = oDir.GetDirectories()
        RcData.lTot = oFiles.Length + oSubDir.Length
        RcData.dlgPB.SetMinMax(0, RcData.lTot)
        For i = 0 To oFiles.Length - 1
            RcData.dlgPB.SetDescription(oFiles(i).FullName)
            If (IsImageFile(oFiles(i).Extension)) Then
                Debug.Print("> Image " & oFiles(i).FullName)
                AppendRcToDb(RcData, oFiles(i))
                System.Windows.Forms.Application.DoEvents()
            Else
                Debug.Print("> File " & oFiles(i).FullName)
            End If
            If (RcData.dlgPB.StepPgb(1) = True) Then
                RcData.bCancel = True
                Return
            End If
        Next

        For i = 0 To oSubDir.Length - 1
            Debug.Print("FOLDER " & oSubDir(i).FullName)
            Debug.Indent()
            Call RecFindImg(RcData, oSubDir(i).FullName)
            Debug.Unindent()
            If (RcData.bCancel = True) Then Return
            System.Windows.Forms.Application.DoEvents()
            If (RcData.dlgPB.StepPgb(1) = True) Then
                RcData.bCancel = True
                Return
            End If
        Next
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    Public Shared Sub GetFavInfo()
        If (Stgs.bHasInit = True) Then Return
        Stgs.bHasInit = True

        Dim bOk As Boolean = True
        Dim sData As DBDATA = Nothing
        sData.ExcelWorkbook = Nothing
        If (Stgs.sFavStr Is Nothing) Then Return
        Try
            If (Start_DB(sData) = True) Then
                For i As Integer = 0 To Stgs.sFavStr.Length - 1
                    With Stgs.sFavStr(i)


                        If (.idx < DBF_Row_1) Then
                            Debug.Print("Fav image at index " & .idx & " discarded (small idx)")
                            .idx = 0
                            Continue For
                        ElseIf .idx >= sData.img_cnt + DBF_Row_1 Then
                            Debug.Print("Fav image at index " & .idx & " discarded (large idx)")
                            .idx = 0
                            Continue For
                        End If

                        bOk = True
                        '// bOk is only modified (to False) in case of failure
                        .id.sName = _
                            sData.ExcelSheet.GetCVStr( _
                            .idx, DBF_ColName)
                        .id.sPath = _
                            sData.ExcelSheet.GetCVStr( _
                            .idx, DBF_ColPath)
                        .id.dNorth = _
                            sData.ExcelSheet.GetCVDbl( _
                            .idx, DBF_ColNins, bOk)
                        .id.dEast = _
                            sData.ExcelSheet.GetCVDbl( _
                            .idx, DBF_ColEins, bOk)
                        .id.dScale = _
                            sData.ExcelSheet.GetCVDbl( _
                            .idx, DBF_ColScl, bOk)
                        .id.dRot = _
                            sData.ExcelSheet.GetCVDbl( _
                            .idx, DBF_ColRot, bOk)

                        If (bOk = False) Then
                            Debug.Print("Fav image at index " & .idx & " discarded (conversion)")
                            .idx = 0
                            Continue For
                        End If
                    End With
                Next
            Else
                CMain.AlertUser(TX.IMGE_DB)
            End If
        Catch ex As System.Exception
            CMain.DebugException(ex)
        Finally
            If (sData.ExcelWorkbook IsNot Nothing) Then
                Stop_DB(sData)
            End If
        End Try
    End Sub
    '// ===================================================================== '

#End Region


#Region "C O M M A N D S"


    '// --------------------------------------------------------------------- '
    '// display settings dialog
    <CommandMethod(sCMD_SETTINGS)> _
    Public Sub Show_Settings()
        Try
            Dim StgD As CST_ImageDb = New CST_ImageDb
            ApplicationServices.Application.ShowModelessDialog(StgD)
        Catch ex As System.Exception
            CMain.DebugException(ex)
            CMain.PopUpExc()
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// check a point
    <CommandMethod(sCMD_POINT)> _
    Public Sub Check_Point()

        Dim dlgSR As CLS_ImageDb = Nothing
        Dim dlgPB As PROGRESS = Nothing
        Dim sData As DBDATA = Nothing
        Dim iMax As Integer = 10
        Dim ICrt As Integer = 0
        ReDim iAry(0 To 10)

        Try
            dlgSR = New CLS_ImageDb

            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
            If (acDoc Is Nothing) Then Exit Try

            Dim db As Database = acDoc.Database
            Dim ed As Editor = acDoc.Editor

            Dim ppo As PromptPointOptions
            Dim ppr As PromptPointResult

            ppo = New PromptPointOptions(vbLf & CMain._T(TX.PICKPOINT) & ":")
            ppr = ed.GetPoint(ppo)
            If ppr.Status <> PromptStatus.OK Then Exit Try

            If (Start_DB(sData) = True) Then
                ' check to see if there are any images
                If (sData.img_cnt = 0) Then
                    CMain.AlertUser(TX.IMGE_EMPTY)
                    Exit Try
                End If

                ' check if any image in the database may help us
                If (ppr.Value.X < sData.Rct.E_1) Or _
                  (ppr.Value.X > sData.Rct.E_2) Or _
                  (ppr.Value.Y < sData.Rct.N_1) Or _
                  (ppr.Value.Y > sData.Rct.N_2) _
                  Then
                    CMain.AlertUser(TX.IMGE_NOI)
                    Exit Try
                End If

                ' prepare to iterate
                dlgPB = New PROGRESS
                dlgPB.InitPgb(CMain._T(TX.IMGSERCH), _
                                DBF_Row_1, _
                                CInt(DBF_Row_1 + sData.img_cnt))
                'cntImgLst = 0
                Dim i As Integer
                Dim bOk As Boolean
                For i = DBF_Row_1 To DBF_Row_1 + sData.img_cnt - 1
                    If (dlgPB.StepPgb(1) = True) Then Exit For

                    If (sData.ExcelSheet.GetCVDbl( _
                            i, _
                            DBF_ColEmin, bOk) _
                        > ppr.Value.X) Then Continue For

                    If (sData.ExcelSheet.GetCVDbl( _
                            i, _
                            DBF_ColEmax, bOk) _
                        < ppr.Value.X) Then Continue For

                    If (sData.ExcelSheet.GetCVDbl( _
                            i, _
                            DBF_ColNmin, bOk) _
                        > ppr.Value.Y) Then Continue For

                    If (sData.ExcelSheet.GetCVDbl( _
                            i, _
                            DBF_ColNmax, bOk) _
                        < ppr.Value.Y) Then Continue For

                    ' this image holds requested point
                    AppendImgToCh(sData, iMax, ICrt, i)
                    
                    System.Windows.Forms.Application.DoEvents()
                Next i
                Call dlgPB.EndPgb()
                dlgPB = Nothing

                If (ICrt = 0) Then
                    CMain.AlertUser(TX.IMGE_NOI)
                    dlgSR.Close()
                    ReDim iAry(-1)
                    iAry = Nothing
                Else
                    ReDim Preserve iAry(0 To ICrt - 1)
                    iMax = ICrt
                    dlgSR.ShowMeLastLst(Me)
                End If
            Else
                CMain.AlertUser(TX.IMGE_DB)
            End If
        Catch ex As System.Exception
            If (ICrt = 0) Then
                '// not shure which is best / proper, so i'll use both
                ReDim iAry(-1)
                iAry = Nothing
            End If
            If Not (dlgSR Is Nothing) Then
                dlgSR.Close()
            End If
            CMain.DebugException(ex)
            CMain.PopUpExc()
        Finally
            If Not (dlgPB Is Nothing) Then
                dlgPB.Close()
            End If
            Stop_DB(sData)
            GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try

    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// check a line
    <CommandMethod(sCMD_LINE)> _
    Public Sub Check_Line()
        Dim dlgSR As CLS_ImageDb = Nothing
        Dim dlgPB As PROGRESS = Nothing
        Dim sData As DBDATA = Nothing
        Dim iMax As Integer = 10
        Dim ICrt As Integer = 0
        ReDim iAry(0 To 10)

        Try
            dlgSR = New CLS_ImageDb

            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
            If (acDoc Is Nothing) Then Exit Try

            Dim db As Database = acDoc.Database
            Dim ed As Editor = acDoc.Editor


            Dim ppo As PromptPointOptions
            Dim ppr As PromptPointResult
            Dim Ln As FSK_LINE
            Dim Rct As FSK_RECT

            ppo = New PromptPointOptions(vbLf & CMain._T(TX.FPOINT) & ":")
            ppr = ed.GetPoint(ppo)
            If ppr.Status <> PromptStatus.OK Then Exit Try
            Ln.N_1 = ppr.Value.Y
            Ln.E_1 = ppr.Value.X

            ppo.BasePoint = ppr.Value
            ppo.UseBasePoint = True
            ppo.Message = vbLf & CMain._T(TX.SPOINT) & ":"
            Do
                ppr = ed.GetPoint(ppo)
                If ppr.Status <> PromptStatus.OK Then Exit Try
                Ln.N_2 = ppr.Value.Y
                Ln.E_2 = ppr.Value.X

                If Math.Abs(Ln.N_1 - Ln.N_2) > 0.001 Then Exit Do
                If Math.Abs(Ln.E_1 - Ln.E_2) > 0.001 Then Exit Do
                CMain.AlertUser(TX.ERR_PTCLOSE)
            Loop


            If (Start_DB(sData) = True) Then
                ' check to see if there are any images
                If (sData.img_cnt = 0) Then
                    CMain.AlertUser(TX.IMGE_EMPTY)
                    Exit Try
                End If

                ' check if any image in the database may help us
                If (CMain.Intersect_LnRect(Ln, sData.Rct) = False) Then
                    CMain.AlertUser(TX.IMGE_NOI)
                    Exit Try
                End If

                ' prepare to iterate
                dlgPB = New PROGRESS
                dlgPB.InitPgb(CMain._T(TX.IMGSERCH), _
                                DBF_Row_1, _
                                CInt(DBF_Row_1 + sData.img_cnt))
                'cntImgLst = 0
                Dim i As Integer
                Dim bOk As Boolean = True
                For i = DBF_Row_1 To DBF_Row_1 + sData.img_cnt - 1
                    If (dlgPB.StepPgb(1) = True) Then Exit For

                    Rct.E_1 = sData.ExcelSheet.GetCVDbl(i, DBF_ColEmin, bOk)
                    Rct.E_2 = sData.ExcelSheet.GetCVDbl(i, DBF_ColEmax, bOk)
                    Rct.N_1 = sData.ExcelSheet.GetCVDbl(i, DBF_ColNmin, bOk)
                    Rct.N_2 = sData.ExcelSheet.GetCVDbl(i, DBF_ColNmax, bOk)
                    If (bOk = False) Then
                        CMain.InformUser( _
                            String.Format(CMain._T(TX.ERR_GETIMGXL), i))
                        bOk = True
                    End If
                    If (CMain.Intersect_LnRect(Ln, Rct)) Then
                        AppendImgToCh(sData, iMax, ICrt, i)
                    End If

                    System.Windows.Forms.Application.DoEvents()
                Next i
                Call dlgPB.EndPgb()

                If (ICrt = 0) Then
                    CMain.AlertUser(TX.IMGE_NOI)
                    dlgSR.Close()
                    ReDim iAry(-1)
                    iAry = Nothing
                Else
                    ReDim Preserve iAry(0 To ICrt)
                    iMax = ICrt
                    dlgSR.ShowMeLastLst(Me)
                End If
            Else
                CMain.AlertUser(TX.IMGE_DB)
            End If
        Catch ex As System.Exception
            If (ICrt = 0) Then
                '// not shure which is best / proper, so i'll use both
                ReDim iAry(-1)
                iAry = Nothing
            End If
            If Not (dlgSR Is Nothing) Then
                dlgSR.Close()
            End If
            CMain.DebugException(ex)
            CMain.PopUpExc()
        Finally
            If Not (dlgPB Is Nothing) Then
                dlgPB.Close()
            End If
            Stop_DB(sData)
            GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try

    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// check a polyline
    <CommandMethod(sCMD_POLY)> _
    Public Sub Check_PLine()
        Dim dlgSR As CLS_ImageDb = Nothing
        Dim dlgPB As PROGRESS = Nothing
        Dim sData As DBDATA = Nothing
        Dim iMax As Integer = 10
        Dim ICrt As Integer = 0
        ReDim iAry(0 To 10)

        Try
            dlgSR = New CLS_ImageDb

            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
            If (acDoc Is Nothing) Then Exit Try

            Dim db As Database = acDoc.Database
            Dim ed As Editor = acDoc.Editor

            Dim peo As PromptEntityOptions
            peo = New PromptEntityOptions(vbLf & CMain._T(TX.SEL_POLY) & ": ")
            peo.SetRejectMessage(vbLf & CMain._T(TX.ESEL_POLY) & "!")
            peo.AddAllowedClass(GetType(Autodesk.AutoCAD.DatabaseServices.Polyline), False)
            Dim per As PromptEntityResult = ed.GetEntity(peo)
            If per.Status <> PromptStatus.OK Then Exit Sub


            If (Start_DB(sData) = True) Then

                ' check to see if there are any images
                If (sData.img_cnt = 0) Then
                    CMain.AlertUser(TX.IMGE_EMPTY)
                    Exit Try
                End If


                Using acTrans As Transaction = _
                    db.TransactionManager.StartTransaction()
                    Try
                        Dim acPoly As Polyline = DirectCast( _
                            acTrans.GetObject(per.ObjectId, OpenMode.ForRead),  _
                            Polyline)

                        ' check if any image in the database may help us
                        Dim RctTst As FSK_RECT
                        RctTst.E_1 = acPoly.GeometricExtents.MinPoint.X
                        RctTst.N_1 = acPoly.GeometricExtents.MinPoint.Y
                        RctTst.E_2 = acPoly.GeometricExtents.MaxPoint.X
                        RctTst.N_2 = acPoly.GeometricExtents.MaxPoint.Y
                        If (CMain.Intersect_RectRect(sData.Rct, RctTst) = False) Then
                            CMain.AlertUser(TX.IMGE_NOI)
                            Exit Try
                        End If
                        ' create an array of lines to test
                        Dim LnAry(0 To acPoly.NumberOfVertices - 1) As FSK_LINE
                        Dim acPt As Point2d
                        Dim LnCnt As Integer = acPoly.NumberOfVertices - 1
                        acPt = acPoly.GetPoint2dAt(0)
                        LnAry(0).E_1 = acPt.X
                        LnAry(0).N_1 = acPt.Y
                        Dim k As Integer
                        For k = 1 To acPoly.NumberOfVertices - 1
                            acPt = acPoly.GetPoint2dAt(k)
                            LnAry(k - 1).E_2 = acPt.X
                            LnAry(k - 1).N_2 = acPt.Y
                            LnAry(k).E_1 = acPt.X
                            LnAry(k).N_1 = acPt.Y
                        Next
                        If (acPoly.Closed = True) Then
                            If Math.Abs(acPt.X - LnAry(0).E_1) > 0.001 Then
                                If Math.Abs(acPt.Y - LnAry(0).N_1) > 0.001 Then
                                    LnAry(UBound(LnAry)).E_2 = LnAry(0).E_1
                                    LnAry(UBound(LnAry)).N_2 = LnAry(0).N_1
                                    LnCnt = LnCnt + 1
                                End If
                            End If
                        End If

                        ' prepare to iterate in rows of database
                        dlgPB = New PROGRESS
                        dlgPB.InitPgb(CMain._T(TX.IMGSERCH), _
                                        DBF_Row_1, _
                                        CInt(DBF_Row_1 + sData.img_cnt))
                        Dim i As Integer
                        Dim bOk As Boolean
                        For i = DBF_Row_1 To DBF_Row_1 + sData.img_cnt - 1
                            If (dlgPB.StepPgb(1) = True) Then Exit For

                            RctTst.E_1 = sData.ExcelSheet.GetCVDbl(i, _
                                                         DBF_ColEmin, bOk)
                            RctTst.E_2 = sData.ExcelSheet.GetCVDbl(i, _
                                                         DBF_ColEmax, bOk)
                            RctTst.N_1 = sData.ExcelSheet.GetCVDbl(i, _
                                                         DBF_ColNmin, bOk)
                            RctTst.N_2 = sData.ExcelSheet.GetCVDbl(i, _
                                                         DBF_ColNmax, bOk)
                            If (bOk = False) Then
                                CMain.InformUser(String.Format(CMain._T(TX.ERR_GETIMGXL), i))
                                bOk = True
                            End If
                            ' compare this rectangle with each line of polyline
                            For k = 0 To LnCnt - 1
                                If (CMain.Intersect_LnRect(LnAry(k), RctTst) = True) Then
                                    AppendImgToCh(sData, iMax, ICrt, i)
                                    Exit For
                                End If
                            Next k
                            System.Windows.Forms.Application.DoEvents()
                        Next i
                        Call dlgPB.EndPgb()


                        acTrans.Abort()
                    Catch ex As System.Exception
                        acTrans.Abort()
                        CMain.DebugException(ex)
                    End Try
                End Using

                If (ICrt = 0) Then
                    CMain.AlertUser(TX.IMGE_NOI)
                    dlgSR.Close()
                    ReDim iAry(-1)
                    iAry = Nothing
                Else
                    ReDim Preserve iAry(0 To ICrt)
                    iMax = ICrt
                    dlgSR.ShowMeLastLst(Me)
                End If
            Else
                CMain.AlertUser(TX.IMGE_DB)
            End If
        Catch ex As System.Exception
            If (ICrt = 0) Then
                '// not shure which is best / proper, so i'll use both
                ReDim iAry(-1)
                iAry = Nothing
            End If
            If Not (dlgSR Is Nothing) Then
                dlgSR.Close()
            End If
            CMain.DebugException(ex)
            CMain.PopUpExc()
        Finally
            If Not (dlgPB Is Nothing) Then
                dlgPB.Close()
            End If
            Stop_DB(sData)
            GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try


    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// Check a rectangle aligned with the axes
    <CommandMethod(sCMD_CONTOUR)> _
    Public Sub Check_Con()
        Dim dlgSR As CLS_ImageDb = Nothing
        Dim dlgPB As PROGRESS = Nothing
        Dim sData As DBDATA = Nothing
        Dim iMax As Integer = 10
        Dim ICrt As Integer = 0
        ReDim iAry(0 To 10)

        Try
            dlgSR = New CLS_ImageDb

            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
            If (acDoc Is Nothing) Then Exit Try

            Dim db As Database = acDoc.Database
            Dim ed As Editor = acDoc.Editor

            Dim ppo As PromptPointOptions
            Dim ppr As PromptPointResult
            Dim Rct As FSK_RECT
            Dim pco As PromptCornerOptions

            ppo = New PromptPointOptions(vbLf & CMain._T(TX.FPOINT) & ":")
            ppr = ed.GetPoint(ppo)
            If ppr.Status <> PromptStatus.OK Then Exit Try
            Rct.N_1 = ppr.Value.Y
            Rct.E_1 = ppr.Value.X

            pco = New PromptCornerOptions(vbLf & CMain._T(TX.SPOINT) & ":", ppr.Value)
            pco.UseDashedLine = True
            Do
                ppr = ed.GetCorner(pco)
                If ppr.Status <> PromptStatus.OK Then Exit Try
                Rct.N_2 = ppr.Value.Y
                Rct.E_2 = ppr.Value.X

                If Math.Abs(Rct.N_1 - Rct.N_2) > 0.001 Then
                    If Math.Abs(Rct.E_1 - Rct.E_2) > 0.001 Then Exit Do
                End If
                CMain.AlertUser(TX.ERR_PTCLOSE)
            Loop

            If (Start_DB(sData) = True) Then
                ' check to see if there are any images
                If (sData.img_cnt = 0) Then
                    CMain.AlertUser(TX.IMGE_EMPTY)
                    Exit Try
                End If

                ' check if any image in the database may help us
                If (CMain.Intersect_RectRect(sData.Rct, Rct) = False) Then
                    CMain.AlertUser(TX.IMGE_NOI)
                    Exit Try
                End If

                ' prepare to iterate
                dlgPB = New PROGRESS
                dlgPB.InitPgb(CMain._T(TX.IMGSERCH), _
                                DBF_Row_1, _
                                CInt(DBF_Row_1 + sData.img_cnt))

                Dim i As Integer
                Dim bOk As Boolean
                Dim RctTst As FSK_RECT

                For i = DBF_Row_1 To DBF_Row_1 + sData.img_cnt - 1
                    If (dlgPB.StepPgb(1) = True) Then Exit For

                    RctTst.E_1 = sData.ExcelSheet.GetCVDbl(i, _
                                                 DBF_ColEmin, bOk)
                    RctTst.E_2 = sData.ExcelSheet.GetCVDbl(i, _
                                                 DBF_ColEmax, bOk)
                    RctTst.N_1 = sData.ExcelSheet.GetCVDbl(i, _
                                                 DBF_ColNmin, bOk)
                    RctTst.N_2 = sData.ExcelSheet.GetCVDbl(i, _
                                                 DBF_ColNmax, bOk)
                    If (bOk = False) Then
                        CMain.InformUser(String.Format(CMain._T(TX.ERR_GETIMGXL), i))
                        bOk = True
                    End If

                    ' compare
                    If (CMain.Intersect_RectRect(RctTst, Rct) = True) Then
                        AppendImgToCh(sData, iMax, ICrt, i)
                    End If
                    System.Windows.Forms.Application.DoEvents()
                Next i
                Call dlgPB.EndPgb() : dlgPB = Nothing

                If (ICrt = 0) Then
                    CMain.AlertUser(TX.IMGE_NOI)
                    dlgSR.Close()
                    ReDim iAry(-1)
                    iAry = Nothing
                Else
                    ReDim Preserve iAry(0 To ICrt)
                    iMax = ICrt
                    dlgSR.ShowMeLastLst(Me)
                End If
            Else
                CMain.AlertUser(TX.IMGE_DB)
            End If
        Catch ex As System.Exception
            If (ICrt = 0) Then
                '// not shure which is best / proper, so i'll use both
                ReDim iAry(-1)
                iAry = Nothing
            End If
            If Not (dlgSR Is Nothing) Then
                dlgSR.Close()
            End If
            CMain.DebugException(ex)
            CMain.PopUpExc()
        Finally
            If Not (dlgPB Is Nothing) Then
                Call dlgPB.EndPgb() : dlgPB = Nothing
            End If
            Stop_DB(sData)
            GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try


    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// show last search
    <CommandMethod(sCMD_REDISPLAY)> _
    Public Sub Redisplay_List()
        Try
            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
            If (acDoc Is Nothing) Then Return
            If (iAry Is Nothing) Then
                CMain.AlertUser(TX.ERR_NOICHC)
                Return
            End If
            Dim dlgSR As CLS_ImageDb = Nothing
            dlgSR = New CLS_ImageDb
            dlgSR.ShowMeLastLst(Me)
        Catch ex As System.Exception
            CMain.DebugException(ex)
            CMain.PopUpExc()
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// add a image
    <CommandMethod(sCMD_ADD)> _
    Public Sub ADD_NewImage()
        Dim sData As DBDATA = Nothing
        Dim dlgPB As PROGRESS = Nothing
        Try
            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
            If (acDoc Is Nothing) Then Exit Try

            Dim db As Database = acDoc.Database
            Dim ed As Editor = acDoc.Editor

            Dim peo As PromptEntityOptions
            peo = New PromptEntityOptions(vbLf & CMain._T(TX.SEL_IMG) & ": ")
            peo.SetRejectMessage(vbLf & CMain._T(TX.ESEL_IMG) & "!")
            peo.AddAllowedClass(GetType(Autodesk.AutoCAD.DatabaseServices.RasterImage), False)
            Dim per As PromptEntityResult = ed.GetEntity(peo)
            If per.Status <> PromptStatus.OK Then Exit Try

            If (Start_DB(sData) = True) Then
                Using acTrans As Transaction = _
                    db.TransactionManager.StartTransaction()
                    Try
                        Dim ri As RasterImage = DirectCast( _
                            acTrans.GetObject(per.ObjectId, OpenMode.ForRead),  _
                            RasterImage)
                        Dim ridef As RasterImageDef = DirectCast( _
                            acTrans.GetObject(ri.ImageDefId, OpenMode.ForRead),  _
                            RasterImageDef)



                        Dim i As Integer = 1
                        ' search this image in database
                        Dim sPath As String = _
                            ridef.SourceFileName.Substring(0, _
                                ridef.SourceFileName.LastIndexOf("\") + 1)
                        Dim sName As String = ridef.SourceFileName.Substring( _
                            sPath.Length)
                        Dim sNUpp = sName.ToUpper()

                        Dim j As Integer


                        ' prepare to iterate
                        dlgPB = New PROGRESS
                        dlgPB.InitPgb(CMain._T(TX.IMGSERCH), _
                                        DBF_Row_1, _
                                    CInt(DBF_Row_1 + sData.img_cnt))
                        i = DBF_Row_1 + sData.img_cnt
                        For j = DBF_Row_1 To DBF_Row_1 + sData.img_cnt - 1
                            If (dlgPB.StepPgb(1) = True) Then Exit For


                            If sNUpp = sData.ExcelSheet.GetCVStr _
                                (j, DBF_ColName).ToUpper Then
                                Dim sPthIn As String = _
                                    sData.ExcelSheet.GetCVStr _
                                        (j, DBF_ColPath)
                                If (sPath.ToUpper = sPthIn.ToUpper) Then

                                    CMain.InformUser(TX.IMG_FND)
                                    i = j
                                    Exit For
                                Else
                                    ' ask if a new entry should not be added
                                    If (MsgBox( _
                                        String.Format(CMain._T(TX.IMG_FNDP), _
                                                       sPthIn), _
                                               MsgBoxStyle.YesNo) _
                                         = MsgBoxResult.Yes) Then
                                        i = j
                                        Exit For
                                    End If
                                End If
                            End If
                            System.Windows.Forms.Application.DoEvents()
                        Next j
                        Call dlgPB.EndPgb() : dlgPB = Nothing

                        Dim out As IMGFD = Nothing
                        GetRstInfo(acDoc, ridef, ri, out)

                        sData.ExcelSheet.SetCV _
                            (i, DBF_ColPath, sPath)
                        sData.ExcelSheet.SetCV _
                            (i, DBF_ColName, sName)
                        sData.ExcelSheet.SetCV _
                            (i, DBF_ColEmin, out.dEastMin)
                        sData.ExcelSheet.SetCV _
                            (i, DBF_ColNmin, out.dNorthMin)
                        sData.ExcelSheet.SetCV _
                            (i, DBF_ColNmax, out.dNorthMax)
                        sData.ExcelSheet.SetCV _
                            (i, DBF_ColEmax, out.dEastMax)
                        sData.ExcelSheet.SetCV _
                            (i, DBF_ColEins, out.rtd.dEast)
                        sData.ExcelSheet.SetCV _
                            (i, DBF_ColNins, out.rtd.dNorth)
                        sData.ExcelSheet.SetCV _
                            (i, DBF_ColScl, out.rtd.dScale)
                        sData.ExcelSheet.SetCV _
                            (i, DBF_ColRot, out.rtd.dRot)

                        '// update the header
                        sData.img_cnt = sData.img_cnt + 1
                        sData.ExcelSheet.SetCV _
                            (DBF_RowEntCnt, DBF_HdrCol_1, sData.img_cnt)

                        sData.ExcelWorkbook.Save()

                        CMain.InformUser(TX.IMGADDED)

                    Catch ex As System.Exception
                        CMain.DebugException(ex)
                    End Try
                End Using
            Else
                CMain.AlertUser(TX.IMGE_DB)
            End If
        Catch ex As System.Exception
            CMain.DebugException(ex)
            CMain.PopUpExc()
        Finally
            If Not (dlgPB Is Nothing) Then
                Call dlgPB.EndPgb() : dlgPB = Nothing
            End If
            Stop_DB(sData)
            GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// add a folder
    <CommandMethod(sCMD_ADDF)> _
    Public Sub ADD_Folder()

        Dim rc As RECURENTFS

        rc.db = Nothing
        rc.lTot = 0
        rc.iAdded = 0
        rc.dlgPB = Nothing
        rc.bCancel = False
        Try

            Dim FolderBrowserDialog1 As _
                    New System.Windows.Forms.FolderBrowserDialog

            With FolderBrowserDialog1
                .RootFolder = Environment.SpecialFolder.Desktop
                .SelectedPath = "C:\"
                .Description = CMain._T(TX.SELPTH)
                If .ShowDialog <> System.Windows.Forms.DialogResult.OK Then
                    Exit Try
                End If
            End With


            rc.acDoc = Application.DocumentManager.MdiActiveDocument
            If (rc.acDoc Is Nothing) Then Exit Try

            'Dim db As Database = rc.acDoc .Database
            'Dim ed As Editor = rc.acDoc .Editor
            '// ------------------------------------------------------
            If (Start_DB(rc.db) = True) Then

                rc.acTrans = _
                    rc.acDoc.Database.TransactionManager.StartTransaction()
                Using rc.acTrans
                    Try
                        Debug.Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
                        Debug.Print("STARTING PATH SEARCH!!!")
                        Debug.Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
                        rc.dlgPB = New PROGRESS
                        rc.dlgPB.InitPgb(CMain._T(TX.IMGSERCH), _
                                0, _
                                0)
                        RecFindImg(rc, FolderBrowserDialog1.SelectedPath)
                        Debug.Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
                        rc.db.ExcelSheet.SetCV _
                            (DBF_RowEntCnt, DBF_HdrCol_1, rc.db.img_cnt)
                        rc.db.ExcelSheet.SetCV _
                            (DBF_RowMinE, DBF_HdrCol_1, rc.db.Rct.E_1)
                        rc.db.ExcelSheet.SetCV _
                            (DBF_RowMinN, DBF_HdrCol_1, rc.db.Rct.N_1)
                        rc.db.ExcelSheet.SetCV _
                            (DBF_RowMaxE, DBF_HdrCol_1, rc.db.Rct.E_2)
                        rc.db.ExcelSheet.SetCV _
                            (DBF_RowMaxN, DBF_HdrCol_1, rc.db.Rct.N_2)
                        Debug.Print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")

                        rc.db.ExcelWorkbook.Save()

                    Catch ex As System.Exception
                        CMain.DebugException(ex)
                    Finally
                        Call rc.dlgPB.EndPgb()
                        rc.dlgPB = Nothing
                        rc.acTrans.Abort()
                    End Try
                End Using
            Else
                CMain.AlertUser(TX.IMGE_DB)
            End If
            rc.db.ExcelWorkbook.Save()
        Catch ex As System.Exception
            CMain.DebugException(ex)
            CMain.PopUpExc()
        Finally
            Stop_DB(rc.db)
            GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try

        CMain.InformUser(String.Format(CMain._T(TX.IMGFLD_IMPOK), rc.iAdded))

    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// Start-up excel with the database
    <CommandMethod(sCMD_EDIT)> _
    Public Sub Open_Database()
        Try
            If System.IO.File.Exists(Stgs.sDBPath) = False Then
                CMain.AlertUser(CMain._T(TX.IMGE_DB) & vbNewLine & _
                    Stgs.sDBPath & vbNewLine & _
                    CMain._T(TX.ERR_FILE))
                Exit Try
            End If
            Dim psi As New ProcessStartInfo()
            With psi
                .FileName = Stgs.sDBPath
                .UseShellExecute = True
            End With
            Process.Start(psi)
        Catch ex As System.Exception
            CMain.PopUpExc()
            CMain.DebugException(ex)
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// Draw a boundary for database covered area
    <CommandMethod(sCMD_DBRECR)> _
    Public Sub Recreate_DB_Boundaries()
        Try
            Dim sData As DBDATA = Nothing
            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
            If (acDoc Is Nothing) Then Exit Try

            Dim db As Database = acDoc.Database
            Dim ed As Editor = acDoc.Editor

            If (Start_DB(sData) = True) Then
                ' check to see if there are any images
                If (sData.img_cnt = 0) Then
                    CMain.AlertUser(TX.IMGE_EMPTY)
                    Exit Try
                End If
                Using acTrans As Transaction = _
                    db.TransactionManager.StartTransaction()
                    Try
                        Dim acPoly As New Polyline(4)
                        acPoly.SetDatabaseDefaults(db)
                        acPoly.AddVertexAt( _
                            acPoly.NumberOfVertices, _
                            New Point2d(sData.Rct.E_1, sData.Rct.N_1), _
                            0, 0, 0)
                        acPoly.AddVertexAt( _
                            acPoly.NumberOfVertices, _
                            New Point2d(sData.Rct.E_2, sData.Rct.N_1), _
                            0, 0, 0)
                        acPoly.AddVertexAt( _
                            acPoly.NumberOfVertices, _
                            New Point2d(sData.Rct.E_2, sData.Rct.N_2), _
                            0, 0, 0)
                        acPoly.AddVertexAt( _
                            acPoly.NumberOfVertices, _
                            New Point2d(sData.Rct.E_1, sData.Rct.N_2), _
                            0, 0, 0)
                        acPoly.Closed = True
                        Dim acBlkTblRec As BlockTableRecord
                        acBlkTblRec = DirectCast(acTrans.GetObject(db.CurrentSpaceId, _
                                          OpenMode.ForWrite), BlockTableRecord)

                        acBlkTblRec.AppendEntity(acPoly)
                        acTrans.AddNewlyCreatedDBObject(acPoly, True)
                        acTrans.Commit()
                    Catch ex As System.Exception
                        acTrans.Abort()
                        CMain.DebugException(ex)
                    End Try
                End Using
            Else
                CMain.AlertUser(TX.IMGE_DB)
            End If

        Catch ex As System.Exception
            CMain.PopUpExc()
            CMain.DebugException(ex)
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// Draw a boundary for database covered area
    <CommandMethod(sCMD_FAV)> _
    Public Sub Show_Favorites_List()
        Try
            Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
            If (acDoc Is Nothing) Then Return
            If (Stgs.sFavStr Is Nothing) Then
                CMain.AlertUser(TX.IMDB_ERRNOFAV)
                Return
            End If

            '// make shure the list of favorite images is loaded with info
            CM_ImageDb.GetFavInfo()

            Dim dlgSR As CLS_ImageDb = Nothing
            dlgSR = New CLS_ImageDb
            dlgSR.ShowMeFav(Me)

        Catch ex As System.Exception
            CMain.DebugException(ex)
            CMain.PopUpExc()
        End Try
        GC.Collect()
        GC.WaitForPendingFinalizers()
    End Sub
    '// ===================================================================== '

    '// --------------------------------------------------------------------- '
    '// Insert a raster image
    Public Shared Function InsertRImage( _
        ByRef acDoc As Document, _
        ByRef Pth As String, _
        ByRef Name As String, _
        ByVal dNorth As Double, ByVal dEast As Double, _
        ByVal dScale As Double, ByVal dRot As Double) As ObjectId

        If (acDoc Is Nothing) Then Return Nothing
        Dim PthName As String = Pth & Name
        Dim RasterName As String
        Dim i As Integer
        Dim RasterEnt As RasterImage
        Dim btr As BlockTableRecord
        Dim RasterDef As RasterImageDef
        Dim ImageDicID As ObjectId
        Dim ImageDefID As ObjectId
        Dim ImageDic As DBDictionary
        Dim Matrix As Geometry.Matrix3d
        Dim acOid As ObjectId

        Dim curUCSMatrix As Matrix3d = _
            acDoc.Editor.CurrentUserCoordinateSystem
        Dim curUCS As CoordinateSystem3d = _
            curUCSMatrix.CoordinateSystem3d

        i = Name.LastIndexOf("."c)
        If i < 0 Then
            RasterName = Name
        Else
            RasterName = Name.Substring(0, i)
        End If

        Dim prvu As Autodesk.AutoCAD.DatabaseServices.UnitsValue
        prvu = acDoc.Database.Insunits
        acDoc.Database.Insunits = UnitsValue.Undefined

        Using acTrans As Transaction = acDoc.Database. _
            TransactionManager.StartTransaction()
            Try
                btr = DirectCast(acTrans.GetObject( _
                    acDoc.Database.CurrentSpaceId, _
                    DatabaseServices.OpenMode.ForWrite),  _
                    BlockTableRecord)

                ' force loading of RasterImage.dbx module 
                ' (needed for 2009 and earlier)
                RasterEnt = New RasterImage
                RasterEnt.Dispose()

                ImageDicID = RasterImageDef.GetImageDictionary(acDoc.Database)
                If ImageDicID.IsNull Then
                    ImageDicID = RasterImageDef.CreateImageDictionary(acDoc.Database)
                End If
                If ImageDicID.IsNull Then
                    CMain.AlertUser(TX.IMGE_DIC)
                    Exit Try
                End If
                ImageDic = DirectCast(acTrans.GetObject(ImageDicID, _
                           DatabaseServices.OpenMode.ForWrite),  _
                        DBDictionary)
                If ImageDic Is Nothing Then
                    CMain.AlertUser(TX.ERR_DBOBJ)
                    Exit Try
                End If

                RasterDef = IsImgInDoc(acDoc, Pth, Name)
                If (RasterDef Is Nothing) Then
                    '// this image is not XREF'ed
                    RasterDef = New RasterImageDef
                    RasterDef.SourceFileName = PthName
                    RasterDef.ActiveFileName = PthName
                    RasterDef.Load()
                End If

                If ImageDic.Contains(RasterName) Then
                    ImageDefID = DirectCast(ImageDic(RasterName), ObjectId)
                Else
                    ImageDic.UpgradeOpen()
                    ImageDefID = ImageDic.SetAt(RasterName, RasterDef)
                    acTrans.AddNewlyCreatedDBObject(RasterDef, True)
                End If

DoInsertReference:
                RasterEnt = New RasterImage
                RasterEnt.SetDatabaseDefaults(acDoc.Database)
                RasterEnt.ColorIndex = 256
                RasterEnt.Linetype = "ByLayer"
                RasterEnt.LineWeight = LineWeight.ByLayer
                RasterEnt.PlotStyleName = "ByLayer"

                Matrix = Geometry.Matrix3d.Scaling( _
                    (dScale * 2500) / RasterDef.Size.X, _
                    New Point3d(0, 0, 0))
                RasterEnt.TransformBy(Matrix)

                RasterEnt.TransformBy(Matrix3d.Rotation(dRot, _
                           curUCS.Zaxis, _
                           New Point3d(0, 0, 0)))
                RasterEnt.TransformBy(Matrix3d.Displacement( _
                           New Vector3d(dEast, dNorth, 0)))


                RasterEnt.ImageDefId = ImageDefID
                btr = DirectCast(acTrans.GetObject( _
                    acDoc.Database.CurrentSpaceId, OpenMode.ForWrite),  _
                    BlockTableRecord)

                btr.AppendEntity(RasterEnt)
                acTrans.AddNewlyCreatedDBObject(RasterEnt, True)


                acTrans.Commit()
            Catch ex As System.Exception
                acTrans.Abort()
                CMain.DebugException(ex)
            End Try
        End Using
        acDoc.Database.Insunits = prvu

        GC.Collect()
        GC.WaitForPendingFinalizers()
        Return acOid
    End Function
    '// ===================================================================== '




#End Region





    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub
End Class
'//  CLASS    =============================================================== '
'//
'//
'//
'//
'//  FUNCTIONS    ----------------------------------------------------------- '

'//  FUNCTIONS    =========================================================== '
'//
'//
'//
'//
'// ------------------------------------------------------------------------- '
'// ========================================================================= '

